package sistemioperativi.es3.rw;

import java.util.LinkedList;

public class MemoriaCondivisa3FIFOSync extends MemoriaCondivisa{
	
	private LinkedList<Thread> codaThread = new LinkedList<Thread>();
	
	private int numLettoriInLettura = 0;
	private boolean scrittoreInScrittura = false;
	
	public synchronized void inizioScrittura() throws InterruptedException {
		
		codaThread.add(Thread.currentThread());
		while(!mioTurnoScrittore()){
			wait();
		}
		
		codaThread.removeFirst();
		scrittoreInScrittura = true;
		
	}

	
	public synchronized void fineScrittura() throws InterruptedException {
	
		scrittoreInScrittura = false;
		notifyAll();
	}

	@Override
	public synchronized void inizioLettura() throws InterruptedException {
		codaThread.add(Thread.currentThread());
		
		while(!mioTurnoLettore()){
			wait();
		}
		
		codaThread.removeFirst();
		numLettoriInLettura++;
	}


	public synchronized void fineLettura() throws InterruptedException {
		
		numLettoriInLettura--;
		notifyAll();
		
	}
	
	private boolean mioTurnoLettore(){
		return !scrittoreInScrittura && codaThread.getFirst() == Thread.currentThread();
		
	}
	
	private boolean mioTurnoScrittore(){
		return numLettoriInLettura == 0 && mioTurnoLettore();
	}
	
}
